package cn.cimoc.config.security;

import cn.cimoc.handler.JWTAuthenticationEntryPoint;
import cn.cimoc.filter.JwtAuthenticationFilter;
import cn.cimoc.filter.JwtAuthorizationFilter;
import cn.cimoc.handler.HttpStatusLoginFailureHandler;
import cn.cimoc.handler.JWTAccessDeniedHandler;
import cn.cimoc.handler.JsonLoginSuccessHandler;
import cn.cimoc.service.JwtService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;


@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsService userDetailsService;

    @Autowired
    JwtService jwtService;

    @Autowired
    PasswordEncoder myPasswordEncoder;

    @Override
    public void configure(WebSecurity web) throws Exception {
        // 配置静态文件不需要认证
        web.ignoring().antMatchers(
                "/swagger-ui/**",
                // swagger api json
                "/v2/api-docs",
                "/swagger-resources/**",
                "/druid/**",
                "/web/**",
                "/bootstrap3/**",
                "/css/**",
                "/images/**",
                "/js/**"
        );
//        web.ignoring().antMatchers("/img/**");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(myPasswordEncoder);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable()
                .authorizeRequests()
                .antMatchers(
                        "/users/login",
                        "/users/reg"
                ).permitAll()
                .anyRequest().authenticated()

                .and()
                .addFilterAt(new JwtAuthenticationFilter(authenticationManager(), myFailureHandler(), mySuccessHandler()), UsernamePasswordAuthenticationFilter.class)
                .addFilter(new JwtAuthorizationFilter(authenticationManager()))
                // 不需要session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .exceptionHandling()
                // 用来解决匿名用户访问无权限资源时的异常
                .authenticationEntryPoint(new JWTAuthenticationEntryPoint())
                // 用来解决认证过的用户访问无权限资源时的异常
                .accessDeniedHandler(new JWTAccessDeniedHandler());
    }

    @Bean
    public AuthenticationFailureHandler myFailureHandler() {
        return new HttpStatusLoginFailureHandler();
    }

    @Bean
    public AuthenticationSuccessHandler mySuccessHandler() {
        return new JsonLoginSuccessHandler(jwtService);
    }

}
